/**
 * RA C3
 * File : OtherRA.cpp
 * @author Rezan Achmad
 */

#include "OtherRA.h"

/**
 * Write all data to disk
 * @param m Menu
 */
bool OtherRA::write_data(Menu* m) {
    // Validate date before
    if (!validate_data(m)) {
        // Data is not yet valid
        return false;
    }
    
    // Write Categories and Products
    write_data_catprd(m);

    // Write Customers
    write_data_cust(m);

    // Write Cart and Cart Items
    write_data_carts(m);
    
    return true;
}

/**
 * Validate all data
 * @param m Menu
 * @return true if all data are valid, false otherwise.
 */
bool OtherRA::validate_data(Menu* m) {    
    // Init variable
    vector<Cart> carts = m->get_carts();
    vector<Cart_item> cart_items = m->get_cart_items();
    vector<Product> prods = m->get_prods();
    int i = 0, j = 0;
    bool valid = true;
    
    // Validate Cart
    // Iterate all carts
    for (i = 0; i < carts.size(); ++i) {
        j = 0;
        // Find cart item
        for (j = 0; j < cart_items.size(); ++j) {
            if (carts[i].get_cart_id() == cart_items[j].get_cart_id()) {
                // Found one cart item
                break;
            }
        }
        
        if (j == cart_items.size()) {
            // Cart item is not found in this cart
            valid = false;
            cout << "No item found in Cart with id #" << carts[i].get_cart_id() << ". Add one / some item(s) to the Cart or delete the Cart." << endl;
        }
    }
    
    // Validate Cart item
    // Iterate all Cart items
    for (i = 0; i < cart_items.size(); ++i) {
        j = 0;
        // Find product
        for (j = 0; j < prods.size(); ++j) {
            if (prods[j].get_prod_id() == cart_items[i].get_prod_id()) {
                // Product is found
                break;
            }
        }
        
        if (j == prods.size()) {
            // Product is not found
            valid = false;
            cout << "Error at Cart items #" << cart_items[i].get_cart_item_id() << ". Product with id #" << cart_items[i].get_prod_id() << " is not found. Please update that cart items." << endl;
        }
    }
    
    // Validate product
    // Iterate all products
    for (i = 0; i < prods.size(); ++i) {
        if (prods[i].get_prod_price() <= 0) {
            valid = false;
            cout << "Error at Product #" << prods[i].get_prod_id() <<". Product price must be grater than zero." << endl;
        }
    }
    
    return valid;
}

/**
 * Write data Category and Product
 * @param m Menu
 */
void OtherRA::write_data_catprd(Menu* m) {
    if (m->get_catprd_filename().empty()) {
        // Category and Product file not yet read before. Terminate.
        return;
    }

    // Open file
    ofstream catprd_file(m->get_catprd_filename().c_str());

    // Get categories
    vector<Category> cats = m->get_cats();

    // Write number of categories
    catprd_file << cats.size() << "\n";

    // Write all categories
    for (int i = 0; i < cats.size(); ++i) {
        catprd_file << cats[i].get_cat_id() << "\t" << cats[i].get_cat_name() << "\n";
    }

    // Write separator
    catprd_file << "\n\n";

    // Get products
    vector<Product> prods = m->get_prods();

    // Write number of products
    catprd_file << prods.size() << "\n";

    // Write all products
    for (int i = 0; i < prods.size(); ++i) {
        catprd_file << prods[i].get_prod_id() << "\t"
                << prods[i].get_cat_id() << "\t"
                << prods[i].get_prod_name() << "\t"
                << prods[i].get_prod_price() << "\n";
    }

    // Close file
    catprd_file.close();
}

/**
 * Write data Customer
 * @param m Menu
 */
void OtherRA::write_data_cust(Menu* m) {
    if (m->get_cust_filename().empty()) {
        // Customer file not yet read before. Terminate.
        return;
    }

    // Open file
    ofstream cust_file(m->get_cust_filename().c_str());

    // Get customers
    vector<Customer> custs = m->get_custs();

    // Write number of customers
    cust_file << custs.size() << "\n";

    // Write all customers
    for (int i = 0; i < custs.size(); ++i) {
        cust_file << custs[i].get_cust_id() << "\t"
                << custs[i].get_cust_name() << "\t"
                << custs[i].get_addr().get_number() << "\t"
                << custs[i].get_addr().get_street() << "\t"
                << custs[i].get_addr().get_postal_code() << "\n";
    }

    // Close file
    cust_file.close();
}

/**
 * Write data Cart and Cart items
 * @param m Menu
 */
void OtherRA::write_data_carts(Menu* m) {
    if (m->get_carts_filename().empty()) {
        // Cart and Cart items not yet read before. Terminate.
        return;
    }

    // Open file
    ofstream carts_file(m->get_carts_filename().c_str());

    // Get carts
    vector<Cart> carts = m->get_carts();

    // Write number of carts
    carts_file << carts.size() << "\n";

    // Write all carts
    // N [Cart_ID Customer_ID Cart_date]. . . 
    for (int i = 0; i < carts.size(); ++i) {
        carts_file << carts[i].get_cart_id() << "\t"
                << carts[i].get_cust_id() << "\t"
                << carts[i].get_cart_purchase_date().year() << "\t"
                << carts[i].get_cart_purchase_date().month() << "\t"
                << carts[i].get_cart_purchase_date().day() << "\n";
    }

    // Write separator
    carts_file << "\n\n";

    // Get cart items
    vector<Cart_item> cart_items = m->get_cart_items();

    // Write number of cart items
    carts_file << cart_items.size() << "\n";

    // Write all cart items
    // N [Cart_item_ID Cart_ID Product_ID Prod_quantity]. . .
    for (int i = 0; i < cart_items.size(); ++i) {
        carts_file << cart_items[i].get_cart_item_id() << "\t"
                << cart_items[i].get_cart_id() << "\t"
                << cart_items[i].get_prod_id() << "\t"
                << cart_items[i].get_prod_qty() << "\n";
    }

    // Close file
    carts_file.close();
}
